package com.zeyu.framework.monitors.mysql.web;

import com.google.common.collect.Lists;
import com.zeyu.framework.core.persistence.Page;
import com.zeyu.framework.core.web.BaseController;
import com.zeyu.framework.core.web.Result;
import com.zeyu.framework.modules.sys.utils.UserUtils;
import com.zeyu.framework.monitors.mysql.MysqlCollector;
import com.zeyu.framework.monitors.mysql.entity.MysqlStatus;
import com.zeyu.framework.monitors.mysql.entity.ProcessStatus;
import com.zeyu.framework.monitors.mysql.service.MysqlService;
import com.zeyu.framework.tools.report.charts.ChartData;
import com.zeyu.framework.tools.report.dynamic.ReportUtils;
import com.zeyu.framework.utils.Collections3;
import com.zeyu.framework.utils.DateUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.servlet.http.HttpServletRequest;
import java.util.List;

/**
 * mysql 监控和操作controller
 * Created by zeyuphoenix on 16/8/27.
 */
@Controller
@RequestMapping(value = "/monitors/mysql")
public class MysqlController extends BaseController {

    // ================================================================
    // Constants
    // ================================================================

    // ================================================================
    // Fields
    // ================================================================

    @Autowired
    private MysqlCollector mysqlCollector;

    @Autowired
    private MysqlService mysqlService;

    // ================================================================
    // Constructors
    // ================================================================

    // ================================================================
    // Methods from/for super Interfaces or SuperClass
    // ================================================================

    // ================================================================
    // Public or Protected Methods
    // ================================================================

    /**
     * 页面
     */
    @RequestMapping(value = {"index", ""})
    public String index() {

        return "modules/monitors/mysql";
    }

    /**
     * 获取最后一次监控的基本信息,这些信息不保存数据库
     */
    @ResponseBody
    @RequestMapping("current")
    public MysqlStatus currentSatatus() {
        MysqlStatus mysqlStatus = mysqlCollector.getMysqlStatus();
        if (mysqlStatus == null) {
            // 未扫描过则扫描一次
            mysqlStatus = mysqlCollector.getCurrentMysqlDBServerStatus();
        }
        mysqlStatus.setHostName(DateUtils.formatDateTimeLocal(mysqlStatus.getUptime() * 1000L));
        return mysqlStatus;
    }


    /**
     * 获取mysql进程列表
     */
    @RequestMapping(value = "processList")
    @ResponseBody
    public Page<ProcessStatus> processList(HttpServletRequest request) {
        Page<ProcessStatus> page = new Page<>(request);
        page.setCount(1);
        page.setList(mysqlCollector.getProcessStatusList());
        return page;
    }

    /**
     * 数据库的监控图表
     * 监控断掉的问题没办法
     */
    @RequestMapping(value = "chartData")
    @ResponseBody
    public ChartData chartData(int type) {

        ChartData chartData = new ChartData();

        // 默认查询是5分钟一次,则1小时12个,一天288个,一个月9000以内,使用带浮动条的全部查看
        List<MysqlStatus> mysqlStatusList = mysqlService.findList(new MysqlStatus());
        if (!Collections3.isEmpty(mysqlStatusList)) {
            // 角度
            List<String> xAxis = Lists.newArrayList();
            // 指标
            List<List<Number>> series = Lists.newArrayList();

            // type --> 1:缓存命中率  2:流量  3:连接数  4:处理数

            // 转换数据
            for (MysqlStatus mysqlStatus : mysqlStatusList) {
                xAxis.add(DateUtils.formatDate(mysqlStatus.getTime(), "dd日HH:mm"));
                if (type == 1) {
                    // 缓存命中率
                    ReportUtils.addSerie(series, 3);
                    // '缓存命中率',
                    series.get(0).add(mysqlStatus.getKeyHits());
                    // '缓存读命中率',
                    series.get(1).add(mysqlStatus.getKeyReadHits());
                    // '缓存写命中率',
                    series.get(2).add(mysqlStatus.getKeyWriteHits());

                } else if (type == 2) {
                    // 流量
                    ReportUtils.addSerie(series, 2);
                    // '平均每秒钟的输入流量，单位为B',
                    series.get(0).add(mysqlStatus.getReceiveBytes());
                    // '平均每秒钟的输出流量，单位为B',
                    series.get(1).add(mysqlStatus.getSendBytes());

                } else if (type == 3) {
                    // 连接数
                    ReportUtils.addSerie(series, 2);
                    // '当前连接数',
                    series.get(0).add(mysqlStatus.getThreadConnections());
                    // '最大连接数',
                    series.get(1).add(mysqlStatus.getMaxConnections());

                } else if (type == 4) {
                    // 处理数
                    ReportUtils.addSerie(series, 2);
                    // '每秒sql执行数',
                    series.get(0).add(mysqlStatus.getQps());
                    // '每秒事务执行数',
                    series.get(1).add(mysqlStatus.getTps());

                }
            }

            chartData.setxAxis(xAxis);
            chartData.setSeries(series);
        }

        return chartData;
    }

    /**
     * 数据库备份
     */
    @RequestMapping(value = "backup")
    @ResponseBody
    public Result backup() {
        Result result = new Result();
        if (MODE_DEMO) {
            result.setStatus(Result.ERROR);
            result.setMessage("演示模式，不允许操作!");
            return result;
        }
        if (!UserUtils.getUser().isAdmin()) {
            result.setStatus(Result.ERROR);
            result.setMessage("只能使用管理员用户才可以操作!");
            return result;
        }
        // TODO
        result.setStatus(Result.SUCCESS);
        result.setMessage("数据库备份成功");
        return result;
    }

    /**
     * 数据库还原
     */
    @RequestMapping(value = "restore")
    @ResponseBody
    public Result restore() {
        Result result = new Result();
        if (MODE_DEMO) {
            result.setStatus(Result.ERROR);
            result.setMessage("演示模式，不允许操作!");
            return result;
        }
        if (!UserUtils.getUser().isAdmin()) {
            result.setStatus(Result.ERROR);
            result.setMessage("只能使用管理员用户才可以操作!");
            return result;
        }
        // TODO
        result.setStatus(Result.SUCCESS);
        result.setMessage("数据库还原成功");
        return result;
    }

    /**
     * 数据库重新启动
     */
    @RequestMapping(value = "restart")
    @ResponseBody
    public Result restart() {
        Result result = new Result();
        if (MODE_DEMO) {
            result.setStatus(Result.ERROR);
            result.setMessage("演示模式，不允许操作!");
            return result;
        }
        if (!UserUtils.getUser().isAdmin()) {
            result.setStatus(Result.ERROR);
            result.setMessage("只能使用管理员用户才可以操作!");
            return result;
        }
        // TODO
        result.setStatus(Result.SUCCESS);
        result.setMessage("数据库重新启动成功");
        return result;
    }

    // ================================================================
    // Getter & Setter
    // ================================================================

    // ================================================================
    // Private Methods
    // ================================================================

    // ================================================================
    // Inner or Anonymous Class
    // ================================================================

    // ================================================================
    // Test Methods
    // ================================================================

}
